#include "DefFile.h"
#include <cmath>

using namespace std;
boost::dynamic_bitset<>*  Generate_LFSR (boost::dynamic_bitset <>* LFSRpol ,boost::dynamic_bitset<>* init_state, int N);
int compute_R (boost::dynamic_bitset<>* lfsr,boost::dynamic_bitset<>* lfsr_z);

void ComputeCandN (double ta, double tb, double p1, double p2, double& val_2, double& val_1){
	cout.precision(5);
	double** mas =new double* [3];
	for (int i=0;i<2;++i)
		mas[i]= new double[3];
	mas[0][0]= sqrt(p1*(1-p1))*ta;	mas[0][1]=p1;	mas[0][2]=1;
	mas[1][0]= -sqrt(p2*(1-p2))*tb;	mas[1][1]=p2;	mas[1][2]=1;
	double q=-mas[1][0]/mas[0][0];
	for (int j=0;j<3;++j)
	{mas [0][j]*=q;mas[0][j]+=mas[1][j];}
	double c=mas [0][1]/mas[0][2];
	double equal[2];
	equal[0]=mas[1][0];
	equal[1]=mas[1][1]-c;
	val_1 =pow(equal[0]/-equal[1],2);
	val_2=c*val_1;
	for (int i=0;i<2;++i)
		delete[] mas[i];
	delete[] mas;
}
//ofstream file ("New FIle");

void CreateLFSRdump(boost::dynamic_bitset<>* LFSRpolL1, int N, map<boost::dynamic_bitset<>*,int >* LFSR, boost::dynamic_bitset<>* lfsr_z){
	int n=LFSRpolL1->size();
	int max =pow(2,n);
	boost::dynamic_bitset<> curr;
	for (int i=0;i<max;++i){
		curr= boost::dynamic_bitset<>(n,i);//create bitset from integer i
		boost::dynamic_bitset<> * d=Generate_LFSR(LFSRpolL1,&curr,N);
		LFSR->insert(make_pair(d,compute_R(d,lfsr_z)));
	}	
	//file.close();
}

boost::dynamic_bitset<>*  Generate_LFSR (boost::dynamic_bitset <>* LFSRpol ,boost::dynamic_bitset<>* init_state, int N){
	boost::dynamic_bitset<>* lfsr = new boost::dynamic_bitset<>(N);
	int n =init_state->size();
	for (int i=0;i<n;++i)
		(*lfsr)[i]=(*init_state)[i];
	for (int i=n;i<N;++i)
		for (int j=0;j<n;++j)
			(*lfsr)[i]^= (*LFSRpol)[j] * (*lfsr)[i-n+j];
	/*
	file<<"begin:";
	for(int i=0;i<(*init_state).size();++i)
	file<<(*init_state)[i];
	file<<endl;

	file<<"POLINOM :";
	for(int i=0;i<(*LFSRpol).size();++i)
	file<<(*LFSRpol)[i];
	file<<endl;

	for(int i=0;i<(*lfsr).size();++i)
	file<<(*lfsr)[i];
	file<<endl;*/
	return lfsr;
}
int compute_R (boost::dynamic_bitset<>* lfsr, boost::dynamic_bitset<>* lfsr_z){
	int R=int();
	for (int i=0;i<lfsr->size();++i)
		R+=(*lfsr)[i]^(*lfsr_z)[i];
	return R;
}
void MapToFile(map<boost::dynamic_bitset<>*,int>* Map_lfsr, const char* file_name){
	ofstream file (file_name);
	boost::dynamic_bitset<>* t;
	for( std::map < boost::dynamic_bitset<> *, int >::iterator ii=Map_lfsr->begin(); ii!=Map_lfsr->end(); ++ii)
	{
		file<< *((*ii).first)<<"    && r= "<<(*ii).second<<endl;
	}
	file.close();
}
void Filter_map(std::map<boost::dynamic_bitset<>*, int >* Map_lfsr ,int C){
	for(map<boost::dynamic_bitset<>*, int >::iterator ii = Map_lfsr->begin(); ii!=Map_lfsr->end();++ii){
		if ((*ii).second >C ) Map_lfsr->erase(ii);
	}
}